#include "newfs.h"

extern struct newfs_super       newfs_super; 
extern struct custom_options    newfs_options;

/**
 * @brief 获取文件名
 * 
 * @param path 
 * @return char* 
 */
char* newfs_get_fname(const char* path) {
    char ch = '/';
    char *q = strrchr(path, ch) + 1;
    return q;
}
/**
 * @brief 计算路径的层级
 * exm: /av/c/d/f
 * -> lvl = 4
 * @param path 
 * @return int 
 */
int newfs_calc_lvl(const char * path) {
    // char* path_cpy = (char *)malloc(strlen(path));
    // strcpy(path_cpy, path);
    char* str = path;
    int   lvl = 0;
    if (strcmp(path, "/") == 0) {
        return lvl;
    }
    while (*str != NULL) {
        if (*str == '/') {
            lvl++;
        }
        str++;
    }
    return lvl;
}
/**
 * @brief 驱动读
 * 
 * @param offset 
 * @param out_content 
 * @param size 
 * @return int 
 */
int newfs_driver_read(int offset, uint8_t *out_content, int size) {
    //计算对齐后偏移量
    int      offset_aligned = NEWFS_ROUND_DOWN(offset, NEWFS_BLOCK_SZ());
    //计算对齐后偏移量
    int      bias           = offset - offset_aligned;
    int      size_aligned   = NEWFS_ROUND_UP((size + bias), NEWFS_BLOCK_SZ());
    
    uint8_t* temp_content   = (uint8_t*)malloc(size_aligned);
    uint8_t* cur            = temp_content;
    
    ddriver_seek(NEWFS_DRIVER(), offset_aligned, SEEK_SET);
    
    // 按IO块读取对齐后的数据到临时缓冲区
    while (size_aligned != 0)
    {
        ddriver_read(NEWFS_DRIVER(), cur, NEWFS_IO_SZ());
        cur          += NEWFS_IO_SZ();
        size_aligned -= NEWFS_IO_SZ();   
    }
    memcpy(out_content, temp_content + bias, size);
    free(temp_content);
    return NEWFS_ERROR_NONE;
}
/**
 * @brief 驱动写
 * 
 * @param offset 
 * @param in_content 
 * @param size 
 * @return int 
 */
int newfs_driver_write(int offset, uint8_t *in_content, int size) {
    int      offset_aligned = NEWFS_ROUND_DOWN(offset, NEWFS_BLOCK_SZ());
    int      bias           = offset - offset_aligned;
    int      size_aligned   = NEWFS_ROUND_UP((size + bias), NEWFS_BLOCK_SZ());
    
    uint8_t* temp_content   = (uint8_t*)malloc(size_aligned);
    uint8_t* cur            = temp_content;

    newfs_driver_read(offset_aligned, temp_content, size_aligned);
    memcpy(temp_content + bias, in_content, size);
    
    ddriver_seek(NEWFS_DRIVER(), offset_aligned, SEEK_SET);
    while (size_aligned != 0)
    {
        ddriver_write(NEWFS_DRIVER(), cur, NEWFS_IO_SZ());
        cur          += NEWFS_IO_SZ();
        size_aligned -= NEWFS_IO_SZ();   
    }

    free(temp_content);
    return NEWFS_ERROR_NONE;
}
/**
 * @brief 将dentry插入到inode中，采用头插法
 * 
 * @param inode 
 * @param dentry 
 * @return int 
 */
int newfs_alloc_dentry(struct newfs_inode* inode, struct newfs_dentry* dentry) {
    // 判断是否需要重新分配一个数据块
    if (inode->dir_cnt % NEWFS_DENTRY_PER_BLK() == 0) {
        inode->block_pointer[inode->block_allocted] = newfs_alloc_data();
        inode->block_allocted++;
    }

    if (inode->dentrys == NULL) {
        inode->dentrys = dentry;
    }
    else {
        dentry->brother = inode->dentrys;
        inode->dentrys = dentry;
    }
    inode->dir_cnt++;
    inode->size += sizeof(struct newfs_dentry);

    return inode->dir_cnt;
}
/**
 * @brief 将dentry从inode的dentrys中取出
 * 
 * @param inode 一个目录的索引结点
 * @param dentry 该目录下的一个目录项
 * @return int 
 */
int newfs_drop_dentry(struct newfs_inode * inode, struct newfs_dentry * dentry) {
    boolean is_find = FALSE;
    struct newfs_dentry* dentry_cursor;
    dentry_cursor = inode->dentrys;
    
    if (dentry_cursor == dentry) {
        inode->dentrys = dentry->brother;
        is_find = TRUE;
    }
    else {
        while (dentry_cursor)
        {
            if (dentry_cursor->brother == dentry) {
                dentry_cursor->brother = dentry->brother;
                is_find = TRUE;
                break;
            }
            dentry_cursor = dentry_cursor->brother;
        }
    }
    if (!is_find) {
        return -NEWFS_ERROR_NOTFOUND;
    }
    inode->dir_cnt--;
    return inode->dir_cnt;
}
/**
 * @brief 分配一个inode，占用位图
 * 
 * @param dentry 该dentry指向分配的inode
 * @return newfs_inode
 */
struct newfs_inode* newfs_alloc_inode(struct newfs_dentry * dentry) {
    struct newfs_inode* inode;
    int byte_cursor = 0; 
    int bit_cursor  = 0; 
    int available_inode_idx  = 0;
    boolean is_find_free_entry = FALSE;
    /* 检查索引节点位图是否有空位 */
    for (byte_cursor = 0; byte_cursor < newfs_super.sz_io; byte_cursor++)
    {
        for (bit_cursor = 0; bit_cursor < UINT8_BITS; bit_cursor++) {
            if((newfs_super.map_inode[byte_cursor] & (0x1 << bit_cursor)) == 0) {    
                newfs_super.map_inode[byte_cursor] |= (0x1 << bit_cursor);
                is_find_free_entry = TRUE;           
                break;
            }
            
        }
        if (is_find_free_entry) {
            break;
        }
    }
    
    available_inode_idx=byte_cursor*8+bit_cursor;

    if (!is_find_free_entry || available_inode_idx >= newfs_super.max_ino)
        return -NEWFS_ERROR_NOSPACE;

    //分配inode节点
    inode = (struct newfs_inode*)malloc(sizeof(struct newfs_inode));
    inode->ino  = available_inode_idx; 
    inode->size = 0;
    inode->block_allocted = 0;

    /* dentry指向inode */
    dentry->inode = inode;
    dentry->ino   = inode->ino;
    /* inode指回dentry */
    inode->dentry = dentry;
    inode->dir_cnt = 0;
    inode->dentrys = NULL;
    
    // 如果索引节点表示普通文件类型，为文件分配所有需要的数据块空间
    if (NEWFS_IS_REG(inode)) {
        for (int i = 0; i < NEWFS_DATA_PER_FILE; i++) {
            inode->data[i] = (uint8_t *)malloc(NEWFS_BLOCK_SZ());
        }
    }
    return inode;
}

/**
 * @brief 额外分配一个数据块
 * @return 分配的数据块号
 */
 int newfs_alloc_data() {
    int byte_cursor       = 0; 
    int bit_cursor        = 0;   
    int available_block_idx = 0;    //空闲数据块号 
    boolean is_find = FALSE;

    for (byte_cursor = 0; byte_cursor < NEWFS_BLKS_SZ(newfs_super.map_data_blks); byte_cursor++) {
        // 再在该字节中遍历8个bit寻找空闲的data位图
        for (bit_cursor = 0; bit_cursor < UINT8_BITS; bit_cursor++) {
            if((newfs_super.map_data[byte_cursor] & (0x1 << bit_cursor)) == 0) {
                // 当前available_block_idx位置空闲
                newfs_super.map_data[byte_cursor] |= (0x1 << bit_cursor);
                is_find = TRUE;
                break;
            }
        }
        if (is_find) {
            break;
        }
    }
    //计算空闲数据块号
    available_block_idx=byte_cursor*8+bit_cursor;

    if (!is_find || available_block_idx >= newfs_super.max_dno) {
        return -NEWFS_ERROR_NOSPACE;
    }
    
    return available_block_idx;
 }

/**
 * @brief 将内存inode及其下方结构全部刷回磁盘
 * 
 * @param inode 
 * @return int 
 */
int newfs_sync_inode(struct newfs_inode * inode) {
    struct newfs_inode_d  inode_d;
    struct newfs_dentry*  dentry_cursor;
    struct newfs_dentry_d dentry_d;
    int ino             = inode->ino;

    //填充磁盘inode数据
    inode_d.ino         = ino;
    inode_d.size        = inode->size;
    inode_d.ftype       = inode->dentry->ftype;
    inode_d.dir_cnt     = inode->dir_cnt;
    inode_d.block_allocted = inode->block_allocted;

    for (int i = 0; i < inode->block_allocted; i++) {
        inode_d.block_pointer[i] = inode->block_pointer[i];
    }

    // 将inode_d自身刷回磁盘
    if (newfs_driver_write(NEWFS_INO_OFS(ino), (uint8_t *)&inode_d, 
                     sizeof(struct newfs_inode_d)) != NEWFS_ERROR_NONE) {
        return -NEWFS_ERROR_IO;
    }

    int offset;
    
    // 如果是目录类型 inode
    if (NEWFS_IS_DIR(inode)) {
        // 获取目录项链表的头指针
        dentry_cursor = inode->dentrys;

        int i = 0;  //block_pointer的索引

        // 遍历该目录的所有目录项

        // 1.遍历当前目录所有分配的目录数据块
        while ((dentry_cursor != NULL)&& (i < inode->block_allocted)) {
            //得到第i个目录数据块的起始偏移量
            offset = NEWFS_DATA_OFS(inode->block_pointer[i]);
            
            // 2.遍历当前数据块中的所有目录项
            int current_dentry_cnt = 0;
            while ((dentry_cursor != NULL)&&(current_dentry_cnt < NEWFS_DENTRY_PER_BLK())) {
                
                // 填充磁盘目录项结构体
                memcpy(dentry_d.fname, dentry_cursor->fname, NEWFS_MAX_FILE_NAME);
                dentry_d.ftype = dentry_cursor->ftype;
                dentry_d.ino = dentry_cursor->ino;

                // 写入目录项到磁盘
                if (newfs_driver_write(offset, (uint8_t *)&dentry_d, 
                    sizeof(struct newfs_dentry_d))!= NEWFS_ERROR_NONE) {
                        return -NEWFS_ERROR_IO;
                }

                // 递归同步目录项关联的 inode
                newfs_sync_inode(dentry_cursor->inode);

                // 移动到下一个兄弟目录项
                dentry_cursor  = dentry_cursor->brother;
                
                // 增加偏移量，准备写入下一个目录项
                offset += sizeof(struct newfs_dentry_d);

                current_dentry_cnt++;
            }

            i++;
        }
    }
    /* 如果当前inode是文件，那么数据是文件内容，直接写即可 */
    else if (NEWFS_IS_REG(inode)) { 

        for (int i = 0; i < inode->block_allocted; i++) {
        
            if (newfs_driver_write(NEWFS_DATA_OFS(inode->block_pointer[i]), 
                    inode->data[i], NEWFS_BLKS_SZ(NEWFS_DATA_PER_FILE)) != NEWFS_ERROR_NONE) {
                return -NEWFS_ERROR_IO;
            }
        
        }

    }
    return NEWFS_ERROR_NONE;
}



/**
 * @brief 删除内存中的一个inode
 * Case 1: Reg File
 * 
 *                  Inode
 *                /      \
 *            Dentry -> Dentry (Reg Dentry)
 *                       |
 *                      Inode  (Reg File)
 * 
 *  1) Step 1. Erase Bitmap     
 *  2) Step 2. Free Inode                      (Function of newfs_drop_inode)
 * ------------------------------------------------------------------------
 *  3) *Setp 3. Free Dentry belonging to Inode (Outsider)
 * ========================================================================
 * Case 2: Dir
 *                  Inode
 *                /      \
 *            Dentry -> Dentry (Dir Dentry)
 *                       |
 *                      Inode  (Dir)
 *                    /     \
 *                Dentry -> Dentry
 * 
 *   Recursive
 * @param inode 
 * @return int 
 */
int newfs_drop_inode(struct newfs_inode * inode) {
    struct newfs_dentry*  dentry_cursor;
    struct newfs_dentry*  dentry_to_free;
    struct newfs_inode*   inode_cursor;

    int byte_cursor = 0;                // 字节位置游标
    int bit_cursor  = 0;                // 位位置游标
    int ino_cursor  = 0;                // 当前遍历的 inode 编号
    boolean is_find = FALSE;            // 标记是否找到对应的 inode 编号
    
    // 检查是否是根目录 inode，根目录不能被删除
    if (inode == newfs_super.root_dentry->inode) {
        return NEWFS_ERROR_INVAL;
    }

    // 如果是目录 inode
    if (NEWFS_IS_DIR(inode)) {
        dentry_cursor = inode->dentrys; // 获取目录项链表的头
        
        // 遍历所有子目录项
        while (dentry_cursor)
        {   
            inode_cursor = dentry_cursor->inode;
            newfs_drop_inode(inode_cursor); //递归删除子inode
            newfs_drop_dentry(inode, dentry_cursor);
            dentry_to_free = dentry_cursor;
            dentry_cursor = dentry_cursor->brother;
            free(dentry_to_free);
        }

        // 遍历 inode 位图，将当前 inode 标记为未使用
        for (byte_cursor = 0; byte_cursor < NEWFS_BLKS_SZ(newfs_super.map_inode_blks); byte_cursor++) {
            for (bit_cursor = 0; bit_cursor < UINT8_BITS; bit_cursor++) {
                if (ino_cursor == inode->ino) { // 找到对应的 inode
                    newfs_super.map_inode[byte_cursor] &= (uint8_t)(~(0x1 << bit_cursor)); // 清除对应位
                    is_find = TRUE;              // 标记为已找到
                    break;
                }
                ino_cursor++;                    // 更新游标
            }
            if (is_find == TRUE) {               // 如果已找到，跳出外层循环
                break;
            }
        }

    }
    // 如果是文件类型
    else {
        // 遍历 inode 位图，将当前 inode 标记为未使用
        for (byte_cursor = 0; byte_cursor < NEWFS_BLKS_SZ(newfs_super.map_inode_blks); byte_cursor++) {
            for (bit_cursor = 0; bit_cursor < UINT8_BITS; bit_cursor++) {
                if (ino_cursor == inode->ino) { // 找到对应的 inode
                    newfs_super.map_inode[byte_cursor] &= (uint8_t)(~(0x1 << bit_cursor)); // 清除对应位
                    is_find = TRUE;              // 标记为已找到
                    break;
                }
                ino_cursor++;                    // 更新游标
            }
            if (is_find == TRUE) {               // 如果已找到，跳出外层循环
                break;
            }
        }
        // 如果当前 inode 有数据，释放数据内存
        if (inode->data)
            free(inode->data);
        free(inode);                             // 释放 inode 本身的内存
    }
    return NEWFS_ERROR_NONE;
}
/**
 * @brief 
 * 
 * @param dentry dentry指向ino，读取该inode
 * @param ino inode唯一编号
 * @return struct newfs_inode* 
 */
struct newfs_inode* newfs_read_inode(struct newfs_dentry * dentry, int ino) {
    //为索引节点inode动态分配内存
    struct newfs_inode* inode = (struct newfs_inode*)malloc(sizeof(struct newfs_inode));
    struct newfs_inode_d inode_d;
    struct newfs_dentry* sub_dentry;
    struct newfs_dentry_d dentry_d;
    int    dir_cnt = 0, i;

    /* 从磁盘读索引结点 */
    if (newfs_driver_read(NEWFS_INO_OFS(ino), (uint8_t *)&inode_d, 
                        sizeof(struct newfs_inode_d)) != NEWFS_ERROR_NONE) {
        return NULL;                    
    }

    //初始化内存中的inode
    inode->dir_cnt = 0;
    inode->ino = inode_d.ino;
    inode->size = inode_d.size;
    inode->dentry = dentry;
    inode->dentrys = NULL;
    inode->block_allocted = inode_d.block_allocted;
    for (int i = 0; i < NEWFS_DATA_PER_FILE; i++) {
        inode->block_pointer[i] = inode_d.block_pointer[i];
    }

    /* 内存中的inode的数据或子目录项部分也需要读出 */
    if (NEWFS_IS_DIR(inode)) {
        dir_cnt = inode_d.dir_cnt;
        int i = 0;
        int offset;

        // 对所有的目录项都进行处理
        // 1.遍历每个数据块
        while((dir_cnt > 0) && (i < NEWFS_DATA_PER_FILE)){
            offset = NEWFS_DATA_OFS(inode->block_pointer[i]);

            // 2.遍历数据块中的目录项
            while((dir_cnt > 0) && (offset + sizeof(struct newfs_dentry_d) < NEWFS_DATA_OFS(inode->block_pointer[i] + 1))){
                if (newfs_driver_read(offset, (uint8_t *)&dentry_d, sizeof(struct newfs_dentry_d)) != NEWFS_ERROR_NONE){
                    return NULL;  
                }
                
                // 用从磁盘中读出的dentry_d更新内存中的sub_dentry 
                sub_dentry = new_dentry(dentry_d.fname, dentry_d.ftype);
                sub_dentry->parent = inode->dentry;
                sub_dentry->ino    = dentry_d.ino; 
                newfs_alloc_dentry(inode, sub_dentry);

                offset += sizeof(struct newfs_dentry_d);
                dir_cnt--;
            }
            
            i++;
        }
    }
    //普通文件则直接读取数据块
    else if (NEWFS_IS_REG(inode)) {
        for (int i = 0; i < inode->block_allocted; i++) {
            inode->data[i] = (uint8_t *)malloc(NEWFS_BLKS_SZ(NEWFS_DATA_PER_FILE));
            if (newfs_driver_read(NEWFS_DATA_OFS(inode->block_pointer[i]), (uint8_t *)inode->data[i], 
                            NEWFS_BLKS_SZ(NEWFS_DATA_PER_FILE)) != NEWFS_ERROR_NONE) {
                return NULL;                    
            }
        }
    }
    return inode;
}
/**
 * @brief 
 * 
 * @param inode 
 * @param dir [0...]
 * @return struct newfs_dentry* 
 */
struct newfs_dentry* newfs_get_dentry(struct newfs_inode * inode, int dir) {
    struct newfs_dentry* dentry_cursor = inode->dentrys;
    int    cnt = 0;
    while (dentry_cursor)
    {
        if (dir == cnt) {
            return dentry_cursor;
        }
        cnt++;
        dentry_cursor = dentry_cursor->brother;
    }
    return NULL;
}
/**
 * @brief 查找文件或目录
 * path: /qwe/ad  total_lvl = 2,
 *      1) find /'s inode       lvl = 1
 *      2) find qwe's dentry 
 *      3) find qwe's inode     lvl = 2
 *      4) find ad's dentry
 *
 * path: /qwe     total_lvl = 1,
 *      1) find /'s inode       lvl = 1
 *      2) find qwe's dentry
 *  
 * 
 * 如果能查找到，返回该目录项
 * 如果查找不到，返回的是上一个有效的路径
 * 
 * path: /a/b/c
 *      1) find /'s inode     lvl = 1
 *      2) find a's dentry 
 *      3) find a's inode     lvl = 2
 *      4) find b's dentry    如果此时找不到了，is_find=FALSE且返回的是a的inode对应的dentry
 * 
 * @param path 
 * @return struct newfs_dentry* 
 */
struct newfs_dentry* newfs_lookup(const char * path, boolean* is_find, boolean* is_root) {
    struct newfs_dentry* dentry_cursor = newfs_super.root_dentry;
    struct newfs_dentry* dentry_ret = NULL;
    struct newfs_inode*  inode; 
    int   total_lvl = newfs_calc_lvl(path);
    int   lvl = 0;
    boolean is_hit;
    char* fname = NULL;
    char* path_cpy = (char*)malloc(sizeof(path));
    *is_root = FALSE;
    strcpy(path_cpy, path);

    if (total_lvl == 0) {                           /* 根目录 */
        *is_find = TRUE;
        *is_root = TRUE;
        dentry_ret = newfs_super.root_dentry;
    }
    fname = strtok(path_cpy, "/");       
    while (fname)
    {   
        lvl++;
        if (dentry_cursor->inode == NULL) {           /* Cache机制 */
            newfs_read_inode(dentry_cursor, dentry_cursor->ino);
        }

        inode = dentry_cursor->inode;

        if (NEWFS_IS_REG(inode) && lvl < total_lvl) {
            //查找到文件，停止路径解析
            dentry_ret = inode->dentry;
            break;
        }
        if (NEWFS_IS_DIR(inode)) {
            dentry_cursor = inode->dentrys;
            is_hit        = FALSE;

            //遍历目录项链表，查找与当前路径名称匹配的子目录项
            while (dentry_cursor)
            {
                if (memcmp(dentry_cursor->fname, fname, strlen(fname)) == 0) {
                    is_hit = TRUE;
                    break;
                }
                dentry_cursor = dentry_cursor->brother;
            }
            
            //未找到目标子目录项，停止
            if (!is_hit) {  
                *is_find = FALSE;
                dentry_ret = inode->dentry;
                break;
            }

            //命中并完成解析，返回
            if (is_hit && lvl == total_lvl) {
                *is_find = TRUE;
                dentry_ret = dentry_cursor;
                break;
            }
        }
        fname = strtok(NULL, "/"); 
    }

    if (dentry_ret->inode == NULL) {
        dentry_ret->inode = newfs_read_inode(dentry_ret, dentry_ret->ino);
    }
    
    return dentry_ret;
}
/**
 * @brief 挂载newfs, Layout 如下
 * 
 * Layout
 * | Super | Inode Map | Data |
 * 
 * IO_SZ = BLK_SZ
 * 
 * 每个Inode占用一个Blk
 * @param options 
 * @return int 
 */
int newfs_mount(struct custom_options options){
    int                 ret = NEWFS_ERROR_NONE;
    int                 driver_fd;
    struct newfs_super_d  newfs_super_d; 
    struct newfs_dentry*  root_dentry;
    struct newfs_inode*   root_inode;

    int                 inode_blks;
    int                 data_blks;
    int                 map_inode_blks;
    int                 map_data_blks;

    int                 super_blks;
    boolean             is_init = FALSE;

    newfs_super.is_mounted = FALSE;

    //打开设备文件
    driver_fd = ddriver_open(options.device);
    if (driver_fd < 0) {
        return driver_fd;
    }

    //填写超级块
    newfs_super.fd = driver_fd;
    ddriver_ioctl(NEWFS_DRIVER(), IOC_REQ_DEVICE_SIZE,  &newfs_super.sz_disk);
    ddriver_ioctl(NEWFS_DRIVER(), IOC_REQ_DEVICE_IO_SZ, &newfs_super.sz_io);
    newfs_super.sz_block = 2*newfs_super.sz_io;
    
    /* 根目录项每次挂载时新建 */
    root_dentry = new_dentry("/", NEWFS_DIR);  

    if (newfs_driver_read(NEWFS_SUPER_OFS, (uint8_t *)(&newfs_super_d), sizeof(struct newfs_super_d)) != NEWFS_ERROR_NONE) {
        return -NEWFS_ERROR_IO;
    }   

    /* 幻数不正确，初始化 */
    if (newfs_super_d.magic_num != NEWFS_MAGIC_NUM) {     
        
        //各块块数
        super_blks = 1;
        map_inode_blks = 1;
        map_data_blks   = 1;
        inode_blks       = NEWFS_INODE_BLKS;
        data_blks        = NEWFS_DATA_BLKS;

        //layout
        newfs_super.max_ino           =   inode_blks;
        newfs_super.max_dno           =   data_blks;

        newfs_super_d.map_inode_blks    =   map_inode_blks;
        newfs_super_d.map_data_blks     =   map_data_blks;
        //各区域偏移量
        newfs_super_d.map_inode_offset  =   NEWFS_SUPER_OFS + super_blks*newfs_super.sz_block;
        newfs_super_d.map_data_offset   =   newfs_super_d.map_inode_offset + map_inode_blks*newfs_super.sz_block;
        newfs_super_d.inode_offset      =   newfs_super_d.map_data_offset + map_data_blks*newfs_super.sz_block;
        newfs_super_d.data_offset       =   newfs_super_d.inode_offset + inode_blks*newfs_super.sz_block;

        newfs_super_d.magic_num         =   NEWFS_MAGIC_NUM;
        newfs_super_d.sz_usage          =   0;
        is_init = TRUE;
    }

    /* 建立 in-memory 结构 */
    newfs_super.sz_usage   = newfs_super_d.sz_usage;      
    
    //建立索引位图
    newfs_super.map_inode = (uint8_t *)malloc(newfs_super.sz_block);
    newfs_super.map_inode_offset = newfs_super_d.map_inode_offset;
    newfs_super.map_inode_blks    = newfs_super_d.map_inode_blks;   
    
    //建立数据位图
    newfs_super.map_data = (uint8_t *)malloc(newfs_super.sz_block);
    newfs_super.map_data_offset = newfs_super_d.map_data_offset;
    newfs_super.map_data_blks    = newfs_super_d.map_data_blks;
    
    // 设置索引节点和数据块的偏移量
    newfs_super.inode_offset = newfs_super_d.inode_offset;
    newfs_super.data_offset = newfs_super_d.data_offset;

	printf("\n------------1--------------------------------------------------------------------\n\n");

    if (newfs_driver_read(newfs_super_d.map_inode_offset, (uint8_t *)(newfs_super.map_inode), 
                        newfs_super.sz_block) != NEWFS_ERROR_NONE) {
        return -NEWFS_ERROR_IO;
    }

    if (newfs_driver_read(newfs_super_d.map_data_offset, (uint8_t *)(newfs_super.map_data), 
                        newfs_super.sz_block) != NEWFS_ERROR_NONE) {
        return -NEWFS_ERROR_IO;
    }

    // 如果是初始化情况，分配根节点
    if (is_init) {
        root_inode = newfs_alloc_inode(root_dentry);
        newfs_sync_inode(root_inode);
    }
    
    // 读取根目录节点并与根目录项关联
    root_inode            = newfs_read_inode(root_dentry, NEWFS_ROOT_INO);  /* 读取根目录 */
    root_dentry->inode    = root_inode;
    newfs_super.root_dentry = root_dentry;
    newfs_super.is_mounted  = TRUE;

    return ret;
}
/**
 * @brief 
 * 
 * @return int 
 */
int newfs_umount() {
    struct newfs_super_d  newfs_super_d; 

    if (!newfs_super.is_mounted) {
        return NEWFS_ERROR_NONE;
    }
    /* 从根节点向下刷写节点 */
    newfs_sync_inode(newfs_super.root_dentry->inode);    

    // 将内存中的超级块信息填充到超级块数据结构中                                    
    newfs_super_d.magic_num           = NEWFS_MAGIC_NUM;
    newfs_super_d.sz_usage            = newfs_super.sz_usage;

    newfs_super_d.map_inode_blks      = newfs_super.map_inode_blks;
    newfs_super_d.map_inode_offset    = newfs_super.map_inode_offset;
    newfs_super_d.inode_offset        = newfs_super.inode_offset;

    newfs_super_d.map_data_blks       = newfs_super.map_data_blks;
    newfs_super_d.map_data_offset     = newfs_super.map_data_offset;
    newfs_super_d.data_offset         = newfs_super.data_offset;
    
    //写回超级块，索引节点位图，数据块位图
    if (newfs_driver_write(NEWFS_SUPER_OFS, (uint8_t *)&newfs_super_d, 
                     sizeof(struct newfs_super_d)) != NEWFS_ERROR_NONE) {
        return -NEWFS_ERROR_IO;
    }

    if (newfs_driver_write(newfs_super_d.map_inode_offset, (uint8_t *)(newfs_super.map_inode), 
                         newfs_super.sz_block) != NEWFS_ERROR_NONE) {
        return -NEWFS_ERROR_IO;
    }

    if (newfs_driver_write(newfs_super_d.map_data_offset, (uint8_t *)(newfs_super.map_data), 
                         newfs_super.sz_block) != NEWFS_ERROR_NONE) {
        return -NEWFS_ERROR_IO;
    }

    //释放位图
    free(newfs_super.map_inode);
    free(newfs_super.map_data);

    ddriver_close(NEWFS_DRIVER());
    return NEWFS_ERROR_NONE;
}
